﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace MoreExtentions
{
    public static class PropertyHelper
    {
        public static void CopyProperties(object source, object target)
        {
            if (source == null || target == null)
                return;

            Type sourceType = source.GetType();
            Type targetType = target.GetType();
            IEnumerable<PropertyMap> propMap = GetProperties(sourceType, targetType);

            foreach (PropertyMap propertyMap in propMap)
            {
                var sourceValue = propertyMap.Source.GetValue(source, null);
                propertyMap.Target.SetValue(target, sourceValue, null);
            }
        }

        private struct PropertyMap
        {
            public PropertyInfo Source { get; set; }
            public PropertyInfo Target { get; set; }
        }

        private static IEnumerable<PropertyMap> GetProperties(Type sourceType, Type targetType)
        {
            PropertyInfo[] sourceProperties = sourceType.GetProperties();
            PropertyInfo[] targetProperties = targetType.GetProperties();
            var properties = (from s in sourceProperties
                              from t in targetProperties
                              where s.Name == t.Name &&
                                    s.CanRead && t.CanWrite &&
                                    s.PropertyType == t.PropertyType &&
                                    ((s.PropertyType.IsValueType && t.PropertyType.IsValueType) ||
                                     (s.PropertyType == typeof(string) && t.PropertyType == typeof(string)))
                              select new PropertyMap { Source = s, Target = t }).ToList();

            return properties;
        }
    }
}